/*
 *	Copyright (C) Ergobyte Informatics S.A. - All Rights Reserved
 *
 * 	This material is proprietary to Ergobyte. The methods and techniques described herein are considered trade secrets
 *	and/or confidential. Reproduction or distribution, in whole or in part, is forbidden except by express written permission.
 */
package com.ergobyte.servo.client;

import java.io.IOException;
import java.io.StreamCorruptedException;

import org.json.JSONException;
import org.json.JSONObject;

import com.ergobyte.servo.client.Result.JsonResult;
import com.ergobyte.servo.client.api.ErgobyteAPI.S_safira;

public class UserSession {

	private static final int IDLE_TIMEOUT = 30 * 60 * 1000; // 30 minutes

	private Connection connection;
	private UserProfile profile;

	public UserSession(Connection connection) {
		this.connection = connection;
	}

	public Result login(String username, String password) throws IOException {
		if(profile != null) throw new IllegalStateException("Please logout first before logging in again");
		Result result = connection.callService(S_safira.name, S_safira.C_login,
				S_safira.P_login_username, username,
				S_safira.P_login_password, password);
		if(!result.isOK()) return result;
		profile = loadProfile();
		return result;
	}

	public UserProfile getProfile() throws IOException {
		return profile;
	}

	public void logout() throws IOException {
		try {
			connection.callService(S_safira.name, S_safira.C_logout);
		}
		finally {
			profile = null;
		}
	}

	public boolean isLoggedIn(boolean forceCheck) {
		if(profile == null) return false;
		if(!forceCheck && connection.getIdleTime() < IDLE_TIMEOUT) return true;
		try {
			if(loadProfile() != null) return true;
		}
		catch(Exception e) {
			// This method is not supposed to throw any exception
		}
		profile = null;
		return false;
	}

	// Internal methods

	private UserProfile loadProfile() throws IOException {
		Result result = connection.callService(S_safira.name, S_safira.C_getCurrentUser);
		if(!result.isOK()) return null;
		if(!(result instanceof JsonResult)) throw new IOException("safira.getCurrentUser() returned an unexpected value");
		JSONObject jsonObject = (JSONObject)((JsonResult)result).getValue();
		try {
			return new UserProfile(jsonObject);
		}
		catch(JSONException e) {
			throw new StreamCorruptedException("Error reading profile data");
		}
	}
}
